package com.me.chat.service.impl.chat;

import com.me.chat.mapper.chat.ChatLatelyMapper;
import com.me.chat.pojo.chat.ChatGroup;
import com.me.chat.pojo.chat.ChatLately;
import com.me.chat.pojo.chat.qo.ChatLatelyQO;
import com.me.chat.pojo.chat.qo.ChatMessageQO;
import com.me.chat.pojo.user.UserInfo;
import com.me.chat.service.chat.ChatGroupService;
import com.me.chat.service.chat.ChatLateService;
import com.me.chat.service.user.UserService;
import com.me.chat.util.RedisKey;
import com.me.chat.util.SimpleUserInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 最近联系人 实现类
 * @Authhor: qiu
 * @Date: 2021/11/23 8:38 下午
 */

@Service
public class ChatLateServiceImpl implements ChatLateService {

    @Autowired
    ChatLatelyMapper chatLatelyMapper;

    @Autowired
    ChatGroupService chatGroupService;

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    @Autowired
    UserService userService;


    @Override
    public List<ChatLately> selChatLately() {
        String userId = SimpleUserInfo.getUserId();
        //获得最近联系人
        List<ChatLately> chatLatelies = chatLatelyMapper.selChatLately(userId);
        //遍历出来，用get set的方式做关联
        chatLatelies.forEach(item -> {
            int type = item.getType();
            //与人聊天
            if(type == 1) {
                //获得目标对象的用户信息 因为用户信息有缓存，可能比left join 还要快？？
                String targetUserId = item.getTargetId();
                //获得目标用户的用户信息
                UserInfo targetUserInfo = userService.getUserInfo(targetUserId);
                //关系人用户信息赋值
                item.setTargetUserInfo(targetUserInfo);
            }else if(type == 2) {
                String groupId = item.getTargetId();
                //找到对应的group信息
                ChatGroup chatGroup = chatGroupService.selChatGroupByGroupId(groupId);
                item.setTargetGroupInfo(chatGroup);
            }
        });

        return chatLatelies;
    }

    /**
     * 针对点对点的最近联系人
     */
    @Override
    @Transactional(rollbackFor=Exception.class)
    public void addChatLately(ChatMessageQO chatMessageQO) {

        String u1Id = chatMessageQO.getSenderId();
        String u2Id = chatMessageQO.getTargetId();
        String message = chatMessageQO.getMessage();
        LocalDateTime now = chatMessageQO.getCreatedTime();
        int msgType = chatMessageQO.getMsgType();
        int targetType = chatMessageQO.getTargetType();

        //创建最近联系人消息1
        ChatLatelyQO u1 = new ChatLatelyQO();
        u1.setOwnerId(u1Id);
        u1.setTargetId(u2Id);
        u1.setUpdateTime(now);
        u1.setType(targetType);
        u1.setMessage(this.filterMessage(msgType,message));

        //创建最近联系人消息1
        ChatLatelyQO u2 = new ChatLatelyQO();
        u2.setOwnerId(u2Id);
        u2.setTargetId(u1Id);
        u2.setUpdateTime(now);
        u2.setType(targetType);
        u2.setMessage(this.filterMessage(msgType,message));
        //查找当前联系人是否存在，从而决定是更新还是新增
        ChatLately u1IsExist = chatLatelyMapper.selChatLatelyByCondition(u1);

        String roomKey = RedisKey.chatNowRoomHashKey();
        //从redis中获取当前聊天的标识
        String flag1 = (String) stringRedisTemplate.opsForHash()
                .get(roomKey, u1Id + RedisKey.SPLIT + targetType + RedisKey.SPLIT + u2Id);

        String flag2 = (String) stringRedisTemplate.opsForHash()
                .get(roomKey, u2Id + RedisKey.SPLIT + targetType + RedisKey.SPLIT + u1Id);
        //说明存在
        if(u1IsExist != null) {

            //如果redis中的key不存在 说明，用户没有在当前聊天室
            if(flag1 == null || ("").equals(flag1)) {
                //未读数量+1
                u1.setNoRead(u1IsExist.getNoRead() + 1);
            }

            //更新
            chatLatelyMapper.upLatelyByCondition(u1);
        }else {
            if(flag1 == null || ("").equals(flag1)) {
                //未读数量+1
                u1.setNoRead(1);
            }
            //不存在则添加
            chatLatelyMapper.addChatLately(u1);
        }

        ChatLately u2IsExist = chatLatelyMapper.selChatLatelyByCondition(u2);
        //说明存在
        if(u2IsExist != null) {

            if(flag2 == null || ("").equals(flag2)) {
                u2.setNoRead(u2IsExist.getNoRead() + 1);
            }

            //更新
            chatLatelyMapper.upLatelyByCondition(u2);
        }else {

            if(flag2 == null || ("").equals(flag2)) {
                u2.setNoRead(1);
            }

            //不存在则添加
            chatLatelyMapper.addChatLately(u2);
        }

    }

    @Override
    public void delChatLately(ChatLatelyQO chatLatelyQO) {
        chatLatelyMapper.delChatLately(chatLatelyQO);
    }

    @Override
    public void upChatLately(ChatLatelyQO chatLatelyQO) {
        chatLatelyMapper.upLatelyByCondition(chatLatelyQO);
    }

    @Override
    public void setRoomFlag(ChatLatelyQO chatLatelyQO) {
        String roomKey = RedisKey.chatNowRoomHashKey();
        String userId = SimpleUserInfo.getUserId();
        chatLatelyQO.setOwnerId(userId);
        //获得消息类型
        int type = chatLatelyQO.getType();
        String targetId = chatLatelyQO.getTargetId();
        //userId + type + targetId 形成当前人所在的聊天室，有这个标识，那么处于来自于该聊天室的lately no-read 将不会增加
        stringRedisTemplate.opsForHash()
                .put(roomKey,userId+RedisKey.SPLIT+type+RedisKey.SPLIT+targetId,"1");

        //清理未阅读量
        this.noReadClear(chatLatelyQO);
    }

    @Override
    public void noReadClear(ChatLatelyQO chatLatelyQO) {
        //更新lately no-read 为空
        chatLatelyQO.setNoRead(0);
        this.upChatLately(chatLatelyQO);
    }

    @Override
    public void removeRoomFlag(ChatLatelyQO chatLatelyQO) {
        String roomKey = RedisKey.chatNowRoomHashKey();
        String userId = SimpleUserInfo.getUserId();
        chatLatelyQO.setOwnerId(userId);
        //获得消息类型
        int type = chatLatelyQO.getType();
        String targetId = chatLatelyQO.getTargetId();
        //userId + type + targetId 形成当前人所在的聊天室，有这个标识，那么处于来自于该聊天室的lately no-read 将不会增加
        stringRedisTemplate.opsForHash()
                .delete(roomKey,userId+RedisKey.SPLIT+type+RedisKey.SPLIT+targetId);
    }

    /**
     * 通过消息类型来返回要在最近联系人里显示出的消息内容
     * @param type
     * @param message
     * @return
     */
    public String filterMessage(int type,String message) {
        switch (type) {
            case 1:
                return message;
            case 3:
                return "[图片]";
            case 4:
                return "[文件]";
            default:
                return "[未知]";
        }
    }
}
